#include "dswvideosession.h"
#include <libdswtools/dswtools.h>

#define INVALID_PLAYPOS -100

static const ST_P2PMSG_T m_vmsg[] = {
	{"MSG_P2P_REPORTID_RESP", NULL, CDswvideosession::cbReportIdResp},
	{"MSG_P2P_ACK_REQ", NULL, CDswvideosession::cbAckReq},
	{"END","", NULL},
};

CDswvideosession::CDswvideosession()
{
}

CDswvideosession::~CDswvideosession()
{
	m_bExitSendThread = true;
	if (m_live_thread_id != NULL)
		pthread_join(m_live_thread_id, NULL);
	if (m_down_thread_id != NULL)
		pthread_join(m_down_thread_id, NULL);
	if (m_playback_thread_id != NULL)
		pthread_join(m_playback_thread_id, NULL);

	delete m_nAudio_Send.pAudioBuffer;

	pthread_mutex_destroy(&m_nSetAction_lock);
	pthread_mutex_destroy(&m_nWriteLock);
	
	LOG4CPLUS_DEBUG(log_dsw, "Destroy video session!");
}

CDswvideosession* CDswvideosession::createNew(LPST_ENV_T pEnv, struct event_base *base, int nfd, int nHeadSize, char* pKey)
{
	struct timeval tv = {15, 0};
	struct bufferevent *pBev = bufferevent_socket_new(base, nfd, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE);
	bufferevent_set_timeouts(pBev, &tv, NULL);
	return new CDswvideosession(pEnv, pBev, nHeadSize, pKey);
}

CDswvideosession::CDswvideosession(LPST_ENV_T pEnv, struct bufferevent * pBev, int nHeadSize, char* pKey)
:  CTcpcombase(pEnv, pBev, nHeadSize)
, m_live_thread_id(NULL)
, m_down_thread_id(NULL)
, m_playback_thread_id(NULL)
, m_nWidth(0)
, m_nHeight(0)
, m_nFps(0)
, m_bExitSendThread(false)
, m_audio_packetcount(0)
, m_nPlayBack_Speed(1)
, m_nPlaybackPos(INVALID_PLAYPOS)
, m_bCanWrite(true)
{
	LOG4CPLUS_DEBUG(log_dsw, "Create video session!");
	CMarkup xml;

	m_nAudio_Send.pAudioBuffer = new unsigned char[A_BITSTREAM_LEN];
	m_nAudio_Send.dwFrameSize = 0;

	pthread_mutex_init(&m_nSetAction_lock, NULL);
	pthread_mutex_init(&m_nWriteLock, NULL);
	
	strcpy(m_sKey, pKey);
	Make_ReportID(xml);
	SendMsg((char*)xml.GetDoc().c_str());
}

void CDswvideosession::Make_ReportID(CMarkup& xml)
{
	void* pParam;
	
	xml.SetDoc("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
	xml.AddElem("Message");
	xml.AddAttrib("Version", "1.0.0");
	xml.AddChildElem("DSW_HEADER");
	xml.IntoElem();
	xml.AddChildElem("MessageType", "MSG_P2P_REPORTID_REQ");
	xml.OutOfElem();
	m_pEnv->pOnNotifyFunc(PMSG_GET_BASIC, pParam);
	xml.AddChildElem("PUA_ID", ((LPST_DEVICE_BASE)pParam)->devid);
	xml.AddChildElem("PUC_COUNT", 1);
	xml.AddChildElem("PUA_SPEAKSTATE", 0);
	xml.AddChildElem("PUA_AUDIOSTATE", 3);
}

void CDswvideosession::SendMsg(char * pMsg)
{
	char sBuffer[1024 * 5];
	int nLen = strlen(pMsg);
	sBuffer[0] = 0x00;
	sBuffer[1] = (char)nLen;
	sBuffer[2] = (char)(nLen >> 8);
	memcpy(sBuffer + HEADSIZE, pMsg, strlen(pMsg));
	sBuffer[HEADSIZE + strlen(pMsg)] = '\0';
	evbuffer_add(bufferevent_get_output(m_pBev), sBuffer, HEADSIZE + strlen(pMsg) + 1);
}

bool CDswvideosession::ProcessMessage_Ex(char* pMsg, int nLen, struct evbuffer *outbuf)
{
	CMarkup xml;

	xml.SetDoc(pMsg);
	if (xml.FindElem("PUC_ID")){
		if (strcmp(m_sPucID, xml.GetData().c_str()) == 0)
			return true;
	}
	return false;
}

bool CDswvideosession::ProcessMessage(char* pMsg, int nLen, struct evbuffer *outbuf)
{
	CMarkup xml;

	if (IsAudioData(pMsg))
		return ProcessAudioData(pMsg);

	if (ProcessMessage_Ex(pMsg, nLen, outbuf))
		return true;
	
	xml.SetDoc(pMsg);
	if(!xml.FindElem("Message"))
		return false;
	xml.IntoElem();
	if(!xml.FindElem("DSW_HEADER"))
		return false;
	xml.IntoElem();
	if(!xml.FindElem("MessageType"))
		return false;
	char smsgreq[64];
	smsgreq[0] = '\0';
	strcpy(smsgreq, xml.GetData().c_str());
	xml.OutOfElem();
	LPST_P2PMSG_T pPos = (LPST_P2PMSG_T)m_vmsg;
	while(strcmp(pPos->sMsgReq, "END") != 0){
		if ((strcmp(pPos->sMsgReq, smsgreq) == 0) && (pPos->pP2PFunc != NULL)){
			return pPos->pP2PFunc(pMsg, pPos->sMsgResp, this);
			break;
		}
		pPos ++;
	}
	return false;
}

bool CDswvideosession::ReportIdResp(void* pXmlPara,const char* pMsgResp)
{
	int ch_num, sub_num, ncount;
	char sbuf[32];
	CMarkup xml;
	CMarkup xmlPara;

	xmlPara.SetDoc((const char*)pXmlPara);
	CMarkup* pXml = &xmlPara;
	if(pXml->FindElem("Message")){
		pXml->IntoElem();
		if(pXml->FindElem("DSW_HEADER")){
			pXml->IntoElem();
			if(pXml->FindElem("MessageType")){
				if(strcmp("MSG_P2P_REPORTID_RESP", pXml->GetData().c_str())==0){
					pXml->OutOfElem();
					pXml->OutOfElem();
					if(pXml->FindChildElem("DSW_RESULT") ){
						pXml->IntoElem();
						pXml->FindChildElem("PUC_ID");
						sprintf(m_sPucID, "%s", pXml->GetChildData().c_str());
						bool bfound = pXml->FindChildElem("SOCK_TYPE");
						char sSockType[32] = {0};
						if (bfound)
							sprintf(sSockType, "%s", pXml->GetChildData().c_str());
						else
							sprintf(sSockType, "%s", "VIDEO");
						if (strcmp(sSockType, "VIDEO") == 0)	{
							m_nSockType = enmSockTypeVideo;
							videoCapToSend((char*)pXml->GetSubDoc().c_str());
						}
						else if (strcmp(sSockType, "DOWN") == 0){
							m_nSockType = enmSockTypeDown;
							video3gpDownToSend((char*)pXml->GetSubDoc().c_str());
						}
						else if (strcmp(sSockType, "REC") == 0){
							m_nSockType = enmSockTypePlay;
							video3gpPlayToSend((char*)pXml->GetSubDoc().c_str());
						}
						return true;
					}
				}
			}
		}
	}
	return false;
}

bool CDswvideosession::AckReq(void* pMsgReq, const char* pMsgResp)
{
	CMarkup xml;

	xml.SetDoc((char*)pMsgReq);
	if(xml.FindElem("Message")){
		xml.IntoElem();
		if (xml.FindElem("PUC_ID")){
			if (strcmp(m_sPucID, xml.GetData().c_str()) == 0)
				return true;
		}
	}
	return false;
}

void CDswvideosession::video3gpPlayToSend(void* pMsg)
{
	void* pParam;
	char sFile[256];
	CMarkup xml;
	int nFileLen;

	xml.SetDoc((const char*)pMsg);
	if (!xml.FindChildElem("FILE"))
		LOG4CPLUS_ERROR(log_dsw, "Can't find playback filename session!");
	else{
		sprintf(sFile, "%s", xml.GetChildData().c_str());

		if(xml.FindChildElem("SPEED"))
			m_nPlayBack_Speed = atoi(xml.GetChildData().c_str());

		pParam = (void*)sFile;
		nFileLen = m_pEnv->pOnNotifyFunc(PMSG_GET_RECFILELEN, pParam);
		if (nFileLen <= 0)
			LOG4CPLUS_ERROR(log_dsw, "No file can be load!");
		else{
			LOG4CPLUS_DEBUG(log_dsw, "Start playback file " << sFile);
			strcpy(m_sFileName, sFile);
			pthread_create(&m_playback_thread_id, NULL, CDswvideosession::cbVideo3gpPlaySendThread, this);
		}
	}
}

void CDswvideosession::video3gpDownToSend(void* pMsg)
{
	void* pParam;
	char sFile[256];
	int nFileLen;
	CMarkup xml;

	xml.SetDoc((const char*)pMsg);
	if (!xml.FindChildElem("FILE"))
		LOG4CPLUS_ERROR(log_dsw, "Can't find download filename session!");
	else{
		sprintf(sFile, "%s", xml.GetChildData().c_str());
		pParam = (void*)sFile;
		nFileLen = m_pEnv->pOnNotifyFunc(PMSG_GET_RECFILELEN, pParam);
		if (nFileLen <= 0)
			LOG4CPLUS_ERROR(log_dsw, "No file can be load!");
		else{
			LOG4CPLUS_DEBUG(log_dsw, "Start download file " << sFile);
			strcpy(m_sFileName, sFile);
			pthread_create(&m_down_thread_id, NULL, CDswvideosession::cbVideo3gpDownSendThread, this);
		}
	}
}

void CDswvideosession::videoCapToSend(void* pMsg)
{

	CMarkup xml;
	xml.SetDoc((const char*)pMsg);
	int nchn = 0;
	int nstream = MAIN_STREAM;

	if(xml.FindChildElem("CHN")){
		nchn = atoi(xml.GetChildData().c_str());
		if ((nchn < 0) || (nchn >= MAX_CHANNEL))
			nchn = 0;
	}
	xml.ResetChildPos();
	if(xml.FindChildElem("STREAM")){
		nstream = atoi(xml.GetChildData().c_str());
		if ((nstream < 0) || (nstream >= MAX_V_BITSTREAM_NUM))
			nstream = MAIN_STREAM_CMD;
	}
	m_chn = nchn;
	m_stream = nstream;

	int nCh = nchn;
	void* pParam = (void*)&nCh;
	m_pEnv->pOnNotifyFunc(PMSG_GET_VIDEOINFO, pParam);
	m_nWidth = MAKE_V_WIDTH(((LPST_CH_PARAM)pParam)->vtype, ((LPST_CH_PARAM)pParam)->bs[(m_stream == MAIN_STREAM_CMD) ? MAIN_STREAM : SUB_STREAM].size);
	m_nHeight = MAKE_V_HEIGHT(((LPST_CH_PARAM)pParam)->vtype, ((LPST_CH_PARAM)pParam)->bs[(m_stream == MAIN_STREAM_CMD) ? MAIN_STREAM : SUB_STREAM].size);
	m_nFps = ((LPST_CH_PARAM)pParam)->bs[(m_stream == MAIN_STREAM_CMD) ? MAIN_STREAM : SUB_STREAM].fps;
	
	pthread_create(&m_live_thread_id, NULL, cbVideoSendThread, this);
}

void CDswvideosession::SendVideoFrame(LPST_VIDEO_FRAME_T pVideoFrame, int nFrameId)
{
	TcpStreamPack nPacket;
	struct timeval tv;
	char* pPos;
	int nLen;
	
	nPacket.packsize = sizeof(TcpStreamHead_V) + pVideoFrame->length;
	memcpy(nPacket.head.nHead_v.sign, LIVE_V_FLAG, LIVE_V_FLAG_SIZE);
	nPacket.head.nHead_v.serial = nFrameId;
	gettimeofday(&tv, NULL);
	nPacket.head.nHead_v.time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
	nPacket.head.nHead_v.width = m_nWidth;
	nPacket.head.nHead_v.height = m_nHeight;
	nPacket.head.nHead_v.fps = m_nFps;
	memset(nPacket.head.nHead_v.retention, 0, sizeof(nPacket.head.nHead_v.retention));
	memcpy(&(nPacket.head.nHead_v.tail), pVideoFrame->pFrame + (pVideoFrame->length - sizeof(nPacket.head.nHead_v.tail)), sizeof(nPacket.head.nHead_v.tail));
	nPacket.head.nHead_v.streamsize = pVideoFrame->length;
	evbuffer_add(bufferevent_get_output(m_pBev), &nPacket, sizeof(nPacket) - sizeof(Un_TcpStreamHead) + sizeof(TcpStreamHead_V));
	pPos = (char*)pVideoFrame->pFrame;
	nLen = pVideoFrame->length;
	while(nLen > TCP_MAX_PACKET_SIZE){
		evbuffer_add(bufferevent_get_output(m_pBev), pPos, TCP_MAX_PACKET_SIZE);
		nLen -= TCP_MAX_PACKET_SIZE;
		pPos += TCP_MAX_PACKET_SIZE;
	}
	if (nLen > 0){
		evbuffer_add(bufferevent_get_output(m_pBev), pPos, nLen);
	}
}

void CDswvideosession::SendAudioFrame(LPST_AUDIO_FRAME_T pAudioFrame, int nFrameId)
{
	LPST_AUDIO_FRAME_T pSendFrame = NULL;
	if (pAudioFrame->bzEncType == STREAM_ENCTYPE_AUDIO_SPEEXPCM16X8K_10PACKET){
		if (m_audio_packetcount < AUDIO_SENDPACKET_SIZE){
			memcpy(m_nAudio_Send.pAudioBuffer + m_nAudio_Send.dwFrameSize,
				pAudioFrame->pAudioBuffer, pAudioFrame->dwFrameSize);
			int nold_framelen = m_nAudio_Send.dwFrameSize;
			int nold_frameid = m_nAudio_Send.dwFrameNumber;
			memcpy(&m_nAudio_Send, &pAudioFrame, sizeof(ST_AUDIO_FRAME_T) - sizeof(unsigned char*));
			m_nAudio_Send.dwFrameSize = nold_framelen + pAudioFrame->dwFrameSize;
			if (nold_frameid != 0)
				m_nAudio_Send.dwFrameNumber = nold_frameid;
			m_audio_packetcount++;
		}
		if (m_audio_packetcount >= AUDIO_SENDPACKET_SIZE){
			pSendFrame = &m_nAudio_Send;
		}
	}
	else
		pSendFrame = pAudioFrame;
	if (pSendFrame == NULL)
		return;

	TcpStreamPack nPacket;
	struct timeval tv;
	char* pPos;
	int nLen;
	
	nPacket.packsize = sizeof(TcpStreamHead_A) - sizeof(unsigned char*) + pSendFrame->dwFrameSize;
	memcpy(nPacket.head.nHead_a.sign, LIVE_A_FLAG, LIVE_A_FLAG_SIZE);
	memcpy(&nPacket.head.nHead_a.nFrame, pSendFrame, sizeof(ST_AUDIO_FRAME_T) - sizeof(unsigned char*));
	evbuffer_add(bufferevent_get_output(m_pBev), &nPacket, sizeof(nPacket) - sizeof(Un_TcpStreamHead) + (sizeof(TcpStreamHead_A) - sizeof(unsigned char*)));

	pPos = (char*)pSendFrame->pAudioBuffer;
	nLen = pSendFrame->dwFrameSize;
	while(nLen > TCP_MAX_PACKET_SIZE){
		evbuffer_add(bufferevent_get_output(m_pBev), pPos, TCP_MAX_PACKET_SIZE);
		nLen -= TCP_MAX_PACKET_SIZE;
		pPos += TCP_MAX_PACKET_SIZE;
	}
	if (nLen > 0){
		evbuffer_add(bufferevent_get_output(m_pBev), pPos, nLen);
	}

	m_nAudio_Send.dwFrameNumber = 0;
	m_nAudio_Send.dwFrameSize = 0;
	m_audio_packetcount = 0;
}

void CDswvideosession::PlaybackDelay(unsigned int nInterval, int nFps, int nSpeed)
{
	int nDuration;
	switch(nSpeed){
	case 2:
		nDuration = (1000 * 1000) / (nFps * 2);
		break;
	case 4:
		nDuration = (1000 * 1000) / (nFps * 4);
		break;
	case -2:
		nDuration = (1000 * 1000) / (nFps / 2);
		break;
	case -4:
		nDuration = (1000 * 1000) / (nFps / 4);
		break;
	default:
		nDuration = (1000 * 1000) / nFps;
		break;
	}
	if (nInterval >= nDuration)
		return;
	struct timeval tv;
	tv.tv_sec = (nDuration - nInterval) / 1000000;
	tv.tv_usec = (nDuration - nInterval) % 1000000;
	select(0, NULL, NULL, NULL, &tv);
}

void CDswvideosession::Video3gpPlaySendThread()
{
	LOG4CPLUS_DEBUG(log_dsw, "Start 3gp playback send thread to puc " << m_sPucID);
	ST_3GP_PLAY_T n3GPPlay;
	void* pParam;
	struct timeval nStartTm, nEndTm;
	ST_PLAYBACK_NODE_T nNode;
	int nSpeed;

	pParam = (void*)&nNode;
	strcpy(nNode.sPucid, m_sPucID);
	nNode.nCmd = EN_ADD_NODE;
	nNode.pSession = this;
	m_pEnv->pOnNotifyFunc(PMSG_UPDATE_PLAYBACKLIST, pParam);
	
	n3GPPlay.pFileName = m_sFileName;
	pParam = (void*)&n3GPPlay;
	if (m_pEnv->pOnNotifyFunc(PMSG_GET_FILERESOLUTION, pParam) == 0){
		n3GPPlay.p3gpFile = NULL;
		n3GPPlay.pBuffer = new unsigned char[V_BITSTREAM_LEN];
		n3GPPlay.bSetPos = false;
		while(!m_pEnv->bExit && !m_bExitSendThread){
			pthread_mutex_lock(&m_nSetAction_lock);
			if (m_nPlaybackPos != INVALID_PLAYPOS){
				n3GPPlay.bSetPos = true;
				n3GPPlay.nSeconds = m_nPlaybackPos;
				m_nPlaybackPos = INVALID_PLAYPOS;
			}
			nSpeed = m_nPlayBack_Speed;
			pthread_mutex_unlock(&m_nSetAction_lock);
			gettimeofday(&nStartTm, NULL);
			n3GPPlay.nLen = V_BITSTREAM_LEN;
			void* pParam = (void*)&n3GPPlay;
			if (m_pEnv->pOnNotifyFunc(PMSG_GET_RECPLAYBACK, pParam) > 0){
				evbuffer_add(bufferevent_get_output(m_pBev), &(n3GPPlay.nLen), sizeof(int));
				evbuffer_add(bufferevent_get_output(m_pBev), n3GPPlay.pBuffer, n3GPPlay.nLen);
			}
			else{
				m_bExitSendThread = true;
				continue;
			}
			gettimeofday(&nEndTm, NULL);
			PlaybackDelay(CDswtools::MakeIntervalTime_us(nStartTm, nEndTm), n3GPPlay.nFps, nSpeed);
		}
		if (n3GPPlay.p3gpFile != NULL)
			delete n3GPPlay.p3gpFile;
		delete n3GPPlay.pBuffer;
	}
	else
		LOG4CPLUS_ERROR(log_dsw, "Can't get file resolution! file = " << n3GPPlay.pFileName);

	LOG4CPLUS_DEBUG(log_dsw, "Exit 3gp playback send thread to puc " << m_sPucID);
	if (m_pBev)
		bufferevent_free(m_pBev);
	m_pBev = NULL;

	pParam = (void*)&nNode;
	strcpy(nNode.sPucid, m_sPucID);
	nNode.nCmd = EN_REMOVE_NODE;
	m_pEnv->pOnNotifyFunc(PMSG_UPDATE_PLAYBACKLIST, pParam);
	delete this;
}

void CDswvideosession::Video3gpDownSendThread()
{
	LOG4CPLUS_DEBUG(log_dsw, "Start 3gp dowload send thread to puc " << m_sPucID);
	ST_DOWNLOAD_T nDownload;
	memset(&nDownload, 0, sizeof(ST_DOWNLOAD_T));
	nDownload.pFileName = m_sFileName;
	nDownload.pBuffer = new unsigned char[DOWNLOAD_SIZE];

	while(!m_pEnv->bExit && !m_bExitSendThread){
		pthread_mutex_lock(&m_nWriteLock);
		if (!m_bCanWrite){
			pthread_mutex_unlock(&m_nWriteLock);
			usleep(1000);
			continue;
		}
		m_bCanWrite = false;
		pthread_mutex_unlock(&m_nWriteLock);

		void* pParam = (void*)&nDownload;
		if (m_pEnv->pOnNotifyFunc(PMSG_GET_RECDOWNLOAD, pParam) > 0){
			evbuffer_add(bufferevent_get_output(m_pBev), &(nDownload.nLen), sizeof(int));
			evbuffer_add(bufferevent_get_output(m_pBev), nDownload.pBuffer, nDownload.nLen);
		}
		else
			m_bExitSendThread = true;
	}

	if (nDownload.fp != NULL)
		fclose(nDownload.fp);
	delete nDownload.pBuffer;
	LOG4CPLUS_DEBUG(log_dsw, "Exit 3gp dowload send thread to puc " << m_sPucID);
	if (m_pBev)
		bufferevent_free(m_pBev);
	m_pBev = NULL;
	delete this;
}

void CDswvideosession::OnWrite(struct bufferevent *bev)
{
	pthread_mutex_lock(&m_nWriteLock);
	m_bCanWrite = true;
	pthread_mutex_unlock(&m_nWriteLock);
}

void CDswvideosession::VideoSendTcpThread()
{
	LOG4CPLUS_DEBUG(log_dsw, "Start video send thread to puc " << m_sPucID);
	ST_VIDEO_FRAME_T nVFrame = {0};
	ST_AUDIO_FRAME_EX_T nAFrame = {0};
	void* pParam;
	unsigned int nVideoSeq = 0;
	unsigned int nVideoFrameId = 0;
	unsigned int nAudioSeq = 0;
	unsigned int nAudioFrameId = 0;
	bool bSendAudio = false;

	nVFrame.ch_num = m_chn;
	nVFrame.sub_num = ((m_stream == MAIN_STREAM_CMD) ? MAIN_STREAM : SUB_STREAM);
	nVFrame.pFrame = NULL;

	nAFrame.ch_num = m_chn;

	m_pEnv->pOnNotifyFunc(PMSG_GET_AUDIOINFO, pParam);
	bSendAudio = (((LPST_AUDIO_PARAM)pParam)->stereo != AUDIO_OFF);
	
	while(!m_pEnv->bExit && !m_bExitSendThread){
		nVFrame.seq = nVideoSeq;
		nVFrame.length = 0;
		pParam = (void*)&nVFrame;
		m_pEnv->pOnNotifyFunc(PMSG_GET_VIDEOFRAME, pParam);
		if (nVFrame.length > 0){
			SendVideoFrame(&nVFrame, nVideoFrameId++);
			nVideoSeq = nVFrame.seq + 1;
		}

		if (bSendAudio){
			nAFrame.nAudioFrame.dwFrameNumber = nAudioSeq;
			nAFrame.nAudioFrame.dwFrameSize = 0;
			pParam = (void*)&nAFrame;
			m_pEnv->pOnNotifyFunc(PMSG_GET_AUDIOFRAME, pParam);
			if ((int)nAFrame.nAudioFrame.dwFrameSize > 0){
				SendAudioFrame(&nAFrame.nAudioFrame, nAudioFrameId++);
				nAudioSeq = nAFrame.nAudioFrame.dwFrameNumber + 1;
			}
		}

		if (bSendAudio){
			if ((nVFrame.length <= 0) && (nAFrame.nAudioFrame.dwFrameSize <= 0))
				usleep(1000 * 10);
		}
		else{
			if (nVFrame.length <= 0)
				usleep(1000 * 10);
		}
	}
	LOG4CPLUS_DEBUG(log_dsw, "Exit video send thread to puc " << m_sPucID);
	if (m_pBev)
		bufferevent_free(m_pBev);
	m_pBev = NULL;
	delete this;
}

void CDswvideosession::OnError(EN_ERR_TYPE nType, struct bufferevent *bev, short events)
{
	m_bExitSendThread = true;
}

bool CDswvideosession::IsAudioData(char* pData)
{
	ENU_STREAMENCTYPE nType = (ENU_STREAMENCTYPE)(*(int*)pData);
	if ((nType == STREAM_ENCTYPE_AUDIO_SPEEXPCM16X8K_10PACKET) ||
		(nType == STREAM_ENCTYPE_AUDIO_G711A_PCM16X8K) ||
		(nType == STREAM_ENCTYPE_AUDIO_PCM16X8K))
		return true;
	return false;
}

bool CDswvideosession::ProcessAudioData(char* pData)
{
	LPST_AUDIO_FRAME_T pFrame = (LPST_AUDIO_FRAME_T)pData;
	void* pParam = (void*)pFrame;
	m_pEnv->pOnNotifyFunc(PMSG_PUT_AUDIOFRAME, pParam);
	return true;
}

